/**
 * ffmpeg 命令行调用封装
 */

import { executeShellCommand } from "./shell.js";
import * as path from "/deno.land/std/path/mod.ts";
import { log } from "./common.js";

// 默认的 ffmpeg 参数
const DEFFAULT_FFMPEG_ARGS = { "-v": "error", "-stats": true };

// 自动处理 `-k` 和 `--k` 两种前缀的参数键
function addKV2Args(key, value, args) {
  if (key.startsWith("--")) { // "--k=v" 格式
    if (typeof (value) !== "boolean") args.push(`${key}=${value}`);
    else args.push(key);
  } else { // "-k v" 格式
    // put key
    if (key.startsWith("-")) args.push(key);
    else args.push(`-${key}`);

    // put value
    if (typeof (value) !== "boolean") args.push(value);
  }
}

/**
 * 执行指定参数的 ffmpeg 命令行
 *
 * @param {Object} cfg 使用对象键值对格式配置的 ffmpeg 命令行参数，键可不添加 `-` 前缀，会自动添加。
 *   会自动处理 `-k` 和 `--k` 两种前缀的参数键。
 *   特别注意，键为 "_" 的值对应 ffmpeg 输出文件列表。
 * @returns {Promise<Deno.ProcessStatus>}
 */
async function ffmpeg(cfg, debug = false) {
  const allArgs = [];

  // 转换为适用于 Deno.run 的数组参数
  for (const [key, value] of Object.entries(cfg)) {
    if (key !== "_") addKV2Args(key, value, allArgs);
  }

  // 在开头添加默认参数
  const startArgs = [];
  for (const [key, value] of Object.entries(DEFFAULT_FFMPEG_ARGS)) {
    if (!allArgs.includes(key)) addKV2Args(key, value, startArgs);
  }
  if (startArgs.length > 0) allArgs.unshift(...startArgs);

  // 添加输出文件参数
  allArgs.push(...cfg["_"]);

  // 在最前面添加 ffmpeg 主命令
  if (allArgs[0] !== "ffmpeg") allArgs.unshift("ffmpeg");

  // debug the args
  if (debug) log(`${allArgs.join(" ")}`);

  // 在执行命令前需要创建输出文件所在的目录，否则 ffmpeg 报错 “No such file or directory”
  cfg["_"].forEach((file) => Deno.mkdirSync(path.dirname(file), { recursive: true }));

  // 执行命令
  await executeShellCommand(allArgs);
}

/**
 * 创建 drawtext 文本水印参数，值的格式为 "drawtext=..."
 *
 * @param {String} text 水印文本
 * @param {String} font 字体文件
 * @param {String} color 字体颜色
 * @param {String} size 字体大小
 * @param {String} position 字体位置
 * @returns {String}
 */
function createTextWatermark({
  text = "Test",
  font = "fonts/HarmonyOS_Sans_Regular.ttf",
  color = "gray@0.5",
  size = "16",
  position = "x=(w-tw-4):y=(h-th-2)",
}) {
  return `drawtext=fontfile=${font}:text='${text}':fontcolor=${color}:fontsize=${size}:${position}`;
}

export { createTextWatermark, ffmpeg };
